package com.ruoyi.common.datapermission.aspect;

import com.ruoyi.common.datapermission.annotation.DataPermission;
import com.ruoyi.common.datapermission.utils.DataPermissionContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

@Aspect
@Slf4j
public class DataPermissionAspect {
    @Pointcut("@annotation(com.ruoyi.common.datapermission.annotation.DataPermission)")
    public void dataPermissionPointCut() {
    }

    @Around("dataPermissionPointCut()")
    public Object dealDataPermission(ProceedingJoinPoint joinPoint) throws Throwable {
        boolean hasDataPermission = false;
        try {
            DataPermission dataPermission = getAnnotation(joinPoint);
            if (dataPermission != null) {
                DataPermissionContextHolder.add(dataPermission);
                hasDataPermission = true;
            }
            return joinPoint.proceed();
        } catch (Exception e) {
            throw e;
        } finally {
            if (hasDataPermission) {
                DataPermissionContextHolder.remove();
            }
        }
    }

    /**
     * 是否存在DataPermission注解，如果存在就获取
     */
    private DataPermission getAnnotation(JoinPoint joinPoint) {
        return getAnnotation(joinPoint, DataPermission.class);
    }

    /**
     * 是否存在注解，如果存在就获取
     */
    private <T extends Annotation> T getAnnotation(JoinPoint joinPoint, Class<T> clazz) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        if (method != null) {
            return method.getAnnotation(clazz);
        }
        return null;
    }
}
